/**
 * count组件;
 */
import { Component, Input, forwardRef } from '@angular/core';
// import { ControlValueAccessor } from '../../directives/control_value_accessor';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS,
  AbstractControl, ValidatorFn, ValidationErrors, FormControl
} from '@angular/forms';

// 1. 创建 EXE_COUNTER_VALUE_ACCESSOR
export const EXE_COUNTER_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CounterComponent),
  multi: true
};

// 2. 定义验证函数
export const validateCounterRange: ValidatorFn = (control: AbstractControl): ValidationErrors => {
  return (control.value > 10 || control.value < 0) ?
    {'rangeError': { current: control.value, max: 10, min: 0 }} : null;
};

// 3. 注册自定义验证器
export const EXE_COUNTER_VALIDATOR = {
  provide: NG_VALIDATORS,
  useValue: validateCounterRange,
  multi: true
};

@Component({
  selector: 'app-counter',
  template: `
    <div>
      <p>当前值：{{count}}</p>
      <button (click)="increment()">++</button>
      <button (click)="decrement()">--</button>
    </div>
  `,
  providers: [EXE_COUNTER_VALUE_ACCESSOR, EXE_COUNTER_VALIDATOR]
})
// export class CounterComponent implements ControlValueAccessor {
//   @Input() count: number = 0;

//   increment() {
//     this.count += 1;
//     this.propagateChange(this.count);
//   }

//   decrement() {
//     this.count -= 1;
//     this.propagateChange(this.count);
//   }

//   // 当表单初始化的时候，将会使用表单模型中对应的初始值作为参数，调用 writeValue() 方法。这意味着，它会覆盖默认值0
//   writeValue(value: any) {
//     if (value) {
//       this.count = value;
//     }
//   }

//   // 当控件接收到 change 事件后，调用的函数
//   registerOnChange(fn: any) {
//     this.propagateChange = fn;
//   }

//   // 当控件接收到 touched 事件后，调用的函数
//   registerOnTouched(fn: any) {}
// }
export class CounterComponent implements ControlValueAccessor {

  @Input() _count: number = 0;

  @Input() counterRangeMin: number;

  @Input() counterRangeMax: number;

  get count() {
    return this._count;
  }

  set count(value: number) {
    this._count = value;
    this.propagateChange(this._count);
  }

  propagateChange = (_: any) => { };

  writeValue(value: any) {
    if (value !== undefined) {
      this.count = value;
    }
  }

  registerOnChange(fn: any) {
    this.propagateChange = fn;
  }

  registerOnTouched(fn: any) { }

  increment() {
    this.count ++;
  }

  decrement() {
    this.count--;
  }
}
